﻿#include "Scheduler.h"
#include "Config.h"
#include "Control.h"
#include "Worker.h"
#include "Algorithm.h"
#include "AlgorithmOnnxRuntimeV8.h"
#include "AlgorithmFaceDetection.h"
#include "GenerateAlarmVideo.h"
#include "Utils/Log.h"
#include "ModelConfig.h"
#include <memory> // 添加智能指针

namespace AVSAnalyzer {
    Scheduler::Scheduler(Config* config) :
        mConfig(config), 
        mState(false),
        mLoopAlarmThread(nullptr)
    {
        LOGI("Scheduler 初始化");
    }

    Scheduler::~Scheduler()
    {
        LOGI("Scheduler 释放资源");

        clearAlarmQueue();

        if (mLoopAlarmThread)
        {
            mLoopAlarmThread->join();
            delete mLoopAlarmThread;
            mLoopAlarmThread = nullptr;
        }

        // 清理所有算法实例
        mAlgorithms.clear();
    }

    Config* Scheduler::getConfig() {
        return mConfig;
    }

    bool Scheduler::initAlgorithm() {
        LOGI("initAlgorithm() 开始");

        // 加载所有算法配置
        if (!ModelConfig::getInstance().loadAllConfigs()) {
            LOGE("加载算法配置失败");
            return false;
        }

        bool hasInitialized = false;
        std::lock_guard<std::mutex> lock(mAlgorithmsMtx);

        // 遍历所有算法配置并初始化算法
        ModelConfig::getInstance().forEachConfig([this, &hasInitialized](const std::string& name, const AlgorithmConfig& config) 
        {
            try {
                std::unique_ptr<Algorithm> algorithm = nullptr;

                if (config.type == "yolov8") {
                    algorithm = std::make_unique<AlgorithmOnnxRuntimeV8>(config);
                }                
                else if(config.type == "facedetection")
                {
                    algorithm = std::make_unique<AlgorithmFaceDetection>(config);
                }
                else 
                {
                    LOGE("不支持的算法类型: %s", config.type.c_str());
                    return;
                }

                if (algorithm) {
                    hasInitialized = true;
                    mAlgorithms.emplace_back(std::move(algorithm));
                    LOGI("初始化算法类型: %s 成功\r\n", config.type.c_str());
                }
            }
            catch (const std::exception& e) {
                LOGE("初始化算法类型: %s 失败, 错误: %s", config.type.c_str(), e.what());
            }
        });

        LOGI("initAlgorithm() 结束");
        return hasInitialized;
    }

    void Scheduler::loop() 
    {
        mLoopAlarmThread = new std::thread(Scheduler::loopAlarmThread, this);
        LOGI("Scheduler 开始循环");
        int64_t l = 0;
        while (mState)
        {
            ++l;
            handleDeleteWorker();        
            std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 防止CPU占用过高
        }
    }

    // 获取所有布控
    int Scheduler::apiControls(std::vector<Control*>& controls) 
    {
        int len = 0;

        mWorkerMapMtx.lock();
        for (auto f = mWorkerMap.begin(); f != mWorkerMap.end(); ++f)
        {
            ++len;
            controls.push_back(f->second->mControl);
        }
        mWorkerMapMtx.unlock();

        return len;
    }
    // 获取指定的布控
    Control* Scheduler::apiControl(std::string& code) 
    {
        Control* control = nullptr;
        mWorkerMapMtx.lock();
        for (auto f = mWorkerMap.begin(); f != mWorkerMap.end(); ++f)
        {
            if (f->first == code) {
                control = f->second->mControl;
            }
        }
        mWorkerMapMtx.unlock();

        return control;
    }
    // 添加布控
    void Scheduler::apiControlAdd(Control* control, int& result_code, std::string& result_msg) {
        if (isAdd(control)) 
        {
            result_msg = "the control is running";
            result_code = 1000;
            return;
        }
        else 
        {
            Worker* worker = new Worker(this, control);
            if (worker->start(result_msg)) 
            {
                if (addWorker(control, worker)) 
                {
                    result_msg = "add success";
                    result_code = 1000;
                }
                else 
                {
                    delete worker;
                    worker = nullptr;
                    result_msg = "add error";
                    result_code = 0;
                }
            }
            else 
            {
                delete worker;
                worker = nullptr;
                result_code = 0;
            }
        }
    }
    // 取消布控
    void Scheduler::apiControlCancel(Control* control, int& result_code, std::string& result_msg) 
    {
        // 获取布控对应的worker
        Worker* worker = getWorker(control);
        if (worker) 
        {
            if (worker->getState()) 
            {
                result_msg = "control is running, ";
            }
            else 
            {
                result_msg = "control is not running, ";
            }

            removeWorker(control);

            result_msg += "cancel success";
            result_code = 1000;
            return;
        }
        else 
        {
            result_msg = "there is no such control";
            result_code = 0;
            return;
        }
    }
    void Scheduler::setState(bool state) 
    {
        mState = state;
    }
    // 获取调度器状态
    bool Scheduler::getState() 
    {
        return mState;
    }
    // 获取布控数量
    int Scheduler::getWorkerSize() 
    {
        mWorkerMapMtx.lock();
        int size = mWorkerMap.size();
        mWorkerMapMtx.unlock();

        return size;
    }
    // 判断布控是否已添加
    bool Scheduler::isAdd(Control* control) 
    {
        mWorkerMapMtx.lock();
        bool isAdd = mWorkerMap.end() != mWorkerMap.find(control->code);
        mWorkerMapMtx.unlock();

        return isAdd;
    }
    // 添加布控
    bool Scheduler::addWorker(Control* control, Worker* worker) 
    {
        bool add = false;

        mWorkerMapMtx.lock();
        bool isAdd = mWorkerMap.end() != mWorkerMap.find(control->code);
        if (!isAdd) {
            mWorkerMap.insert(std::pair<std::string, Worker* >(control->code, worker));
            add = true;
        }
        mWorkerMapMtx.unlock();

        return add;
    }
    // 删除布控
    bool Scheduler::removeWorker(Control* control) 
    {
        bool result = false;

        mWorkerMapMtx.lock();
        auto f = mWorkerMap.find(control->code);
        if (mWorkerMap.end() != f) 
        {
            Worker* worker = f->second;

            // 添加到待删除队列start
            std::unique_lock <std::mutex> lck(mTobeDeletedWorkerQ_mtx);
            mTobeDeletedWorkerQ.push(worker);
            //mTobeDeletedWorkerQ_cv.notify_all();
            mTobeDeletedWorkerQ_cv.notify_one();
            // 添加到待删除队列end

            result = mWorkerMap.erase(control->code) != 0;
        }
        mWorkerMapMtx.unlock();

        return result;
    }
    // 获取布控对应的worker
    Worker* Scheduler::getWorker(Control* control) 
    {
        Worker* worker = nullptr;

        mWorkerMapMtx.lock();
        auto f = mWorkerMap.find(control->code);
        if (mWorkerMap.end() != f) 
        {
            worker = f->second;
        }
        mWorkerMapMtx.unlock();

        return worker;
    }
    // 处理待实际删除队列
    void Scheduler::handleDeleteWorker() 
    {
        // 等待条件变量
        std::unique_lock <std::mutex> lck(mTobeDeletedWorkerQ_mtx);
        mTobeDeletedWorkerQ_cv.wait(lck);

        while (!mTobeDeletedWorkerQ.empty()) 
        {
            Worker* worker = mTobeDeletedWorkerQ.front();
            mTobeDeletedWorkerQ.pop();
            LOGI("code=%s,streamUrl=%s", worker->mControl->code.data(), worker->mControl->streamUrl.data());
            delete worker;
            worker = nullptr;
        }
    }
    // 处理报警队列
    void Scheduler::handleLoopAlarm() 
    {       
        int alarmQSize;      // 获取报警队列大小

        while (true) 
        {
            Alarm* alarm = nullptr;
            if (getAlarm(alarm, alarmQSize)) 
            {

                GenerateAlarmVideo gen(mConfig,alarm);
                gen.genAlarmVideo();

                delete alarm;
                alarm = nullptr;
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(10)); // 等待10ms,防止cpu占用过高
        }    
    }
    // 报警处理线程
    void Scheduler::loopAlarmThread(void* arg) 
    {
        Scheduler* scheduler = (Scheduler*)arg;
        scheduler->handleLoopAlarm();
    }

    void Scheduler::addAlarm(Alarm* alarm) 
    {
        mAlarmQ_mtx.lock();
        if (mAlarmQ.size() > 0) 
        {
            //扔掉
            delete alarm;
            alarm = nullptr;
        }
        else 
        {
            mAlarmQ.push(alarm);
        }
   
        mAlarmQ_mtx.unlock();
    }
    // 获取报警
    bool Scheduler::getAlarm(Alarm*& alarm, int& alarmQSize) 
    {
        mAlarmQ_mtx.lock();

        if (!mAlarmQ.empty()) 
        {
            alarm = mAlarmQ.front();
            mAlarmQ.pop();
            alarmQSize = mAlarmQ.size();
            mAlarmQ_mtx.unlock();

            return true;
        }
        else 
        {
            alarmQSize = 0;
            mAlarmQ_mtx.unlock();

            return false;
        }
    }
    // 清空报警队列
    void Scheduler::clearAlarmQueue()
    {
        mAlarmQ_mtx.lock();
        while (!mAlarmQ.empty()) 
        {
            delete mAlarmQ.front();
            mAlarmQ.pop();
        }
        mAlarmQ_mtx.unlock();
    }
}
